package com.dgut.Service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dgut.Service.AuthService;
import com.dgut.Service.utils.JwtTokenUtils;
import com.dgut.dao.IAuthRepository;
import com.dgut.domain.Auth;
import com.dgut.domain.IRole;
import com.dgut.domain.IUser;
import com.dgut.domain.ResultCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

@Service("authServiceImpl")
public class AuthServiceImpl implements AuthService {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private IUserDetailService userDetailsService;

    @Autowired
    private JwtTokenUtils jwtTokenUtil;

    @Autowired
    private IAuthRepository iAuthRepository;


    @Value("${jwt.tokenHead}")
    private String tokenHead;


    @Override
    public IUser register(IUser iUser) {
        final String username = iUser.getUsername();
        if (iAuthRepository.findByUsername(username) != null) {
            System.out.println("用户名为空");
        }
//        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
//        final String rawPassword = iUser.getPassword();
//        iUser.setPassword(encoder.encode(rawPassword));
//        userDetail.setLastPasswordResetDate(new Date());
//        iAuthRepository.insert(iUser);
//        long roleId = iUser.getRole().getId();
//        IRole role = iAuthRepository.findRoleById(roleId);
//        iUser.setRole(role);
//        iAuthRepository.insertRole(iUser.getId(), roleId);
        return iUser;
    }

    @Override
    public Auth login(String username, String password) {
        //用户验证
        final Authentication authentication = authenticate(username, password);


        //存储认证信息
        SecurityContextHolder.getContext().setAuthentication(authentication);

        //生成token
        final IUser userDetail = (IUser) authentication.getPrincipal();
        final String token = jwtTokenUtil.generateAccessToken(userDetail);
        //存储token
        jwtTokenUtil.putToken(username, token);

        return new Auth(token, userDetail);
    }

    @Override
    public void logout(String token) {
        token = token.substring(tokenHead.length());
        String userName = jwtTokenUtil.getUsernameFromToken(token);
        jwtTokenUtil.deleteToken(userName);
    }

    @Override
    public Auth refresh(String oldToken) {
//        String token = oldToken.substring(tokenHead.length());
//        String username = jwtTokenUtil.getUsernameFromToken(token);
//        IUser userDetail = (IUser) userDetailsService.loadUserByUsername(username);
//        if (jwtTokenUtil.canTokenBeRefreshed(token, userDetail.getLastPasswordResetDate())) {
//            token = jwtTokenUtil.refreshToken(token);
//            return new Auth(token, userDetail);
//        }
        return null;
    }

    @Override
    public IUser getUserByToken(String token) {
        token = token.substring(tokenHead.length());
        return jwtTokenUtil.getUserFromToken(token);
    }

    private Authentication authenticate(String username, String password) {
        try {
            //该方法会去调用userDetailsService.loadUserByUsername()去验证用户名和密码，如果正确，则存储该用户名密码到“security 的 context中”
            return authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
        } catch (DisabledException | BadCredentialsException e) {
            System.out.println(ResultCode.LOGIN_ERROR + e.getMessage());
        }
        return null;
    }
}

